<script setup>
import 'video.js/dist/video-js.css'
import videojs from 'video.js'
import 'videojs-contrib-hls'
import 'videojs-flvjs-es6'
import { onMounted, ref, watch, onBeforeUnmount, nextTick } from 'vue'

// pollfill
if (typeof Object.assign != 'function') {
    Object.defineProperty(Object, 'assign', {
        value(target) {
            if (target == null) {
                throw new TypeError(
                    'Cannot convert undefined or null to object'
                )
            }
            const to = Object(target)
            for (let index = 1; index < arguments.length; index++) {
                const nextSource = arguments[index]
                if (nextSource != null) {
                    for (const nextKey in nextSource) {
                        if (
                            Object.prototype.hasOwnProperty.call(
                                nextSource,
                                nextKey
                            )
                        ) {
                            to[nextKey] = nextSource[nextKey]
                        }
                    }
                }
            }
            return to
        },
        writable: true,
        configurable: true,
    })
}
// as of videojs 6.6.0
const DEFAULT_EVENTS = [
    'loadeddata',
    'canplay',
    'canplaythrough',
    'play',
    'pause',
    'waiting',
    'playing',
    'ended',
    'error',
]
const props = defineProps({
    crossOrigin: {
        type: String,
        default: '',
    },
    playsinline: {
        type: Boolean,
        default: false,
    },
    customEventName: {
        type: String,
        default: 'statechanged',
    },
    events: {
        type: Array,
        default: () => [],
    },
    options: {
        type: Object,
        required: true,
    },
    globalOptions: {
        type: Object,
        default: () => ({
            autoplay: true,
            controls: false,
            // preload: 'auto',
            // fluid: false,
            // muted: false,
            controlBar: {
                remainingTimeDisplay: false,
                playToggle: {},
                progressControl: {},
                fullscreenToggle: {},
                volumeMenuButton: {
                    inline: false,
                    vertical: true,
                },
            },
            techOrder: ['html5'],
            plugins: {},
        }),
    },
})
let player = null
const reseted = ref(true)
onMounted(() => {
    if (player) {
        initialize()
    }
})
onBeforeUnmount(() => {
    if (player) {
        dispose()
    }
})
const liveVideoRef = ref()
const videoWrapRef = ref()
const emitEvents = DEFAULT_EVENTS.concat(props.events)
console.log(emitEvents)
const emits = defineEmits(['statechanged'])
function initialize() {
    if (
        !props.options ||
        !props.options.sources ||
        props.options.sources.length == 0
    )
        return
    // videojs options
    const videoOptions = Object.assign({}, props.globalOptions, props.options)
    // let videoEl = this.$el.querySelector('video')
    // ios fullscreen
    if (props.playsinline) {
        liveVideoRef.value.setAttribute('playsinline', props.playsinline)
        liveVideoRef.value.setAttribute('webkit-playsinline', props.playsinline)
        liveVideoRef.value.setAttribute('x5-playsinline', props.playsinline)
        liveVideoRef.value.setAttribute('x5-video-player-type', 'h5')
        liveVideoRef.value.setAttribute('x5-video-player-fullscreen', false)
    }
    // cross origin
    if (props.crossOrigin !== '') {
        liveVideoRef.value.crossOrigin = props.crossOrigin
        liveVideoRef.value.setAttribute('crossOrigin', props.crossOrigin)
    }
    // emit event
    const emitPlayerState = (event, value) => {
        if (event) {
            emits(event, player)
        }
        if (value) {
            emits(props.customEventName, { [event]: value })
        }
    }
    // avoid error "VIDEOJS: ERROR: Unable to find plugin: __ob__"
    if (videoOptions.plugins) {
        delete videoOptions.plugins.__ob__
    }
    // videoOptions
    // console.log('videoOptions', videoOptions)

    // player
    if (
        videoOptions.sources[0] &&
        videoOptions.sources[0].type == 'video/x-flv'
    ) {
        videoOptions.flvjs = {
            mediaDataSource: {
                isLive: true,
                cors: false,
                withCredentials: false,
            },
        }
    }

    let $video = videoWrapRef.value.querySelector('video')
    player = videojs(
        $video,
        videoOptions,
        function () {
            // events
            const events = DEFAULT_EVENTS.concat(props.events)
            // watch events
            const onEdEvents = {}
            for (let i = 0; i < events.length; i++) {
                if (
                    typeof events[i] === 'string' &&
                    onEdEvents[events[i]] === undefined
                ) {
                    ;((event) => {
                        onEdEvents[event] = null
                        this.on(event, () => {
                            emitPlayerState(event, true)
                        })
                    })(events[i])
                }
            }
            // watch timeupdate
            this.on('timeupdate', function () {
                emitPlayerState('timeupdate', currentTime())
            })
            // player readied
            emits('ready', this)
        },
        (err) => {
            console.log(err)
        }
    )
}
function currentTime() {}
function dispose(callback) {
    if (player && player.dispose) {
        if (player.techName_ !== 'Flash') {
            player.pause && player.pause()
        }
        player.dispose()
        if (!videoWrapRef.value.querySelector('video')) {
            const video = document.createElement('video')
            video.className = 'video-js'
            if (props.crossOrigin !== '') {
                video.crossOrigin = props.crossOrigin
                video.setAttribute('crossOrigin', props.crossOrigin)
            }
            videoWrapRef.value.appendChild(video)
        }
        player = null
        nextTick(() => {
            reseted.value = false
            nextTick(() => {
                reseted.value = true
                nextTick(() => {
                    callback && callback()
                })
            })
        })
    }
}
function play() {
    if (player) {
        player.play()
    }
}
function pause() {
    if (player) {
        player.pause()
    }
}
function render() {
    dispose(() => {
        if (
            props.options &&
            props.options.sources &&
            props.options.sources.length
        ) {
            initialize()
        }
    })
}
defineExpose({ play, pause, render })
watch(
    props.options,
    (options) => {
        console.log('options change', options)
        // 		this.dispose(() => {
        // 			if (options && options.sources && options.sources.length) {
        // 				this.initialize()
        // 			}
        // 		})
    },
    { deep: true, immediate: true }
)
</script>
<template>
    <div style="width: 100%; height: 100%" ref="videoWrapRef">
        <video class="video-js vjs-default-skin" ref="liveVideoRef">
            <!-- <source src="https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8" type="application/x-mpegURL" /> -->
            <!-- <source src="http://img.ksbbs.com/asset/Mon_1704/15868902d399b87.flv" type="video/x-flv" /> -->
        </video>
    </div>
</template>

<style>
.video-js {
    width: 100%;
    height: 100%;
}
</style>
